package ru.nsu.ccfit.kalah.view.field;


import android.graphics.PointF;
import android.view.animation.Animation;
import android.view.animation.Transformation;

import java.util.List;
import java.util.Random;

class BallAnimation extends Animation {
    AnimationListener animationListener;

    @Override
    public void setAnimationListener(AnimationListener animationListener) {
        this.animationListener = animationListener;
    }

    private List<Ball> balls;
    private List<PointF> beginPoints;
    private List<PointF> endPoints;
    private PointF middlePoint;

    BallAnimation(final List<Ball> balls, final List<PointF> beginPoints, final List<PointF> endPoints) {
        this.balls = balls;
        this.beginPoints = beginPoints;
        this.endPoints = endPoints;

        this.middlePoint = calculateMiddle();


        super.setAnimationListener(new AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
                if (animationListener != null) {
                    animationListener.onAnimationStart(animation);
                }
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                for (int i = 0; i < balls.size(); i++) {

                    balls.get(i).getPosition().set(endPoints.get(i).x, endPoints.get(i).y);
                }



                if (animationListener != null) {
                    animationListener.onAnimationEnd(animation);
                }
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
                if (animationListener != null) {
                    animationListener.onAnimationRepeat(animation);
                }
            }
        });
    }

    private PointF calculateMiddle() {
        int randX = (50 - new Random().nextInt(100));
        int randY = (50 - new Random().nextInt(100));
        PointF begin = averagePoint(beginPoints);
        PointF end = averagePoint(endPoints);
        PointF point = new PointF((begin.x + end.x) / 2 + randX, (begin.y + end.y) / 2 + randY);
        return point;
    }

    private PointF averagePoint(List<PointF> points) {
        PointF average = new PointF();
        for (PointF point : points) {
            average.x += point.x;
            average.y += point.y;

        }
        average.x /= points.size();
        average.y /= points.size();
        return average;
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        float A = (1 - interpolatedTime) * (1 - interpolatedTime);
        float B = 2 * interpolatedTime * (1 - interpolatedTime);
        float C = interpolatedTime * interpolatedTime;

        for (int i = 0; i < balls.size(); i++) {
            float x = A * beginPoints.get(i).x + B * middlePoint.x + C * endPoints.get(i).x;
            float y = A * beginPoints.get(i).y + B * middlePoint.y + C * endPoints.get(i).y;

            balls.get(i).getPosition().set(x, y);
        }

    }
}
